import { FC, memo, ReactElement, useEffect, useMemo, useRef } from "react";
import ReactDOM from "react-dom";

import { CacheDispatchOptions, Status } from "./KeepAliveScope";
interface ScopedItemProps {
	cacheId: string;
	children?: ReactElement;
	status: Status;
	dispatch?: (options: CacheDispatchOptions) => void;
	loadElement?: (arg: HTMLDivElement) => void;
}

const keepChange = (pre: ScopedItemProps, next: ScopedItemProps) => {
	return pre.status === next.status;
};

const ScopedItem: FC<ScopedItemProps> = props => {
	const { cacheId, children, status, loadElement, dispatch } = props;
	const domRef = useRef<HTMLDivElement | null>(null);
	const domStyle = {
		display: status === "unActive" ? "none" : "block"
	};

	const element = ReactDOM.createPortal(
		<div ref={domRef} style={domStyle}>
			{useMemo(() => (["active", "unActive"].includes(status) ? children : null), [children, status])}
		</div>,
		document.body
	);

	useEffect(() => {
		if (status === "active") {
			loadElement && loadElement(domRef.current!);
		}

		if (status === "unActive") {
			/* 如果处于休眠状态，那么把 dom 元素重新挂载到 body 上 */
			document.body.appendChild(domRef.current!);
			dispatch &&
				dispatch({
					action: "ACTION_UNACTIVE",
					payload: {
						cacheId
					}
				});
		}
	}, [cacheId, dispatch, loadElement, status]);

	return element;
};

export default memo(ScopedItem, keepChange);
